package com.bluedot.utils;


import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.bluedot.excel.AutoColumnWidthStrategy;
import com.bluedot.excel.CustomerCellStyleStrategy;
import com.bluedot.pojo.bo.ExcelLog;
import com.bluedot.pojo.vo.LogVo;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.*;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * excel工具类
 * @author QiYu
 */
public class ExcelUtils {

    /**
     * 复制字节时，默认的缓冲区大小
     */
    private static final int BUFFER_SIZE = 1024;


    public static <T> XSSFWorkbook getWorkbook(Collection<T> dataSet, String[] params, String[] titles) {
        // 校验变量和预期输出excel列数是否相同
        if (params.length != titles.length) {
            System.out.println("变量参数有误");
            return null;
        }
        // 存储每一行的数据
        List<String[]> list = new ArrayList<>();
        for (Object obj : dataSet) {
            // 获取到每一行的属性值数组
            list.add(getValues(obj, params));
        }
        return getWorkbook(titles, list);
    }

    public static XSSFWorkbook getWorkbook(String[] titles, List<String[]> list) {
        // 定义表头
        String[] title = titles;
        // 创建excel工作簿
        XSSFWorkbook workbook = new XSSFWorkbook();
        // 创建工作表sheet
        XSSFSheet sheet = workbook.createSheet();
        // 创建第一行
        XSSFRow row = sheet.createRow(0);
        XSSFCell cell = null;
        // 插入第一行数据的表头
        for (int i = 0; i < title.length; i++) {
            cell = row.createCell(i);
            cell.setCellValue(title[i]);
        }
        int idx = 1;
        for (String[] strings : list) {
            XSSFRow nrow = sheet.createRow(idx++);
            XSSFCell ncell = null;
            for (int i = 0; i < strings.length; i++) {
                ncell = nrow.createCell(i);
                ncell.setCellValue(strings[i]);
            }
        }
        // 设置自动列宽
        for (int i = 0; i < title.length; i++) {
            sheet.autoSizeColumn(i);
            sheet.setColumnWidth(i, sheet.getColumnWidth(i) * 16 / 10);
        }
        return workbook;
    }

    // 根据需要输出的变量名数组获取属性值
    public static String[] getValues(Object object, String[] params) {
        String[] values = new String[params.length];
        try {
            for (int i = 0; i < params.length; i++) {
                Field field = object.getClass().getDeclaredField(params[i]);
                // 设置访问权限为true
                field.setAccessible(true);
                // 获取属性
                // 如果属性有涉及基本变量的做一个转换
                if (field.getType() == com.sun.org.apache.bcel.internal.generic.Type.INT.getClass()) {
                    values[i] = String.valueOf((int) field.get(object));
                }
                values[i] = field.get(object).toString();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return values;
    }


//    =======================================================================

    /**
     * 将pojo的log对象转化为Excel
     */
    public static InputStream logToExcel(List<LogVo> list, ByteArrayOutputStream out) {
        ArrayList<ExcelLog> excelLogs = new ArrayList<>();
        for (LogVo log : list) {
            excelLogs.add(new ExcelLog(log));
        }

        //调用easyExcel里面的方法实现写操作
        WriteSheet writeSheet0 = EasyExcel.writerSheet(0, "日志信息").head(ExcelLog.class).build();
        // 如果是浏览器下载, 需要设置不关闭流
        ExcelWriter excelWriter = EasyExcel.write(out)
                .autoCloseStream(Boolean.TRUE)
                .excelType(ExcelTypeEnum.XLSX)
                .registerWriteHandler(new CustomerCellStyleStrategy())
                .registerWriteHandler(new AutoColumnWidthStrategy())
                .build();
        //写数据

        excelWriter.write(excelLogs, writeSheet0);
        excelWriter.finish();
        InputStream in = new ByteArrayInputStream(out.toByteArray());
        closeOutStream(out);
        return in;
    }


    /**
     * 用于关闭输入流（不用try）
     */
    public static void closeInStream(InputStream in) {
        if (in != null) {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 用于关闭输出流（不用try）
     */
    public static void closeOutStream(OutputStream out) {
        if (out != null) {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {

    }

}
